<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" >

<title>django-simpleui组件中模型的CRUD的重写 | janl&#39;s workspace</title>

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="shortcut icon" href="https://janl.gitee.io/favicon.ico?v=1658806429692">
<link rel="stylesheet" href="https://janl.gitee.io/styles/main.css">



<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>



    <meta name="description" content="最的工作中处理一个使用django项目，项目主要以提供restfull的api为主，但是也使用django-simpleui组件实现了一个简单的管理后台，对系统中的一些基础数据和配置进行管理，因为需求调整，需要对原来模型在CRUD时做一些额..." />
    <meta name="keywords" content="python,django" />
  </head>
  <body>
    <div id="app" class="main">

      <div class="sidebar" :class="{ 'full-height': menuVisible }">
  <div class="top-container" data-aos="fade-right">
    <div class="top-header-container">
      <a class="site-title-container" href="https://janl.gitee.io">
        <img src="https://janl.gitee.io/images/avatar.png?v=1658806429692" class="site-logo">
        <h1 class="site-title">janl&#39;s workspace</h1>
      </a>
      <div class="menu-btn" @click="menuVisible = !menuVisible">
        <div class="line"></div>
      </div>
    </div>
    <div>
      
        
          <a href="/" class="site-nav">
            首页
          </a>
        
      
        
          <a href="/archives" class="site-nav">
            归档
          </a>
        
      
        
          <a href="/tags" class="site-nav">
            标签
          </a>
        
      
        
          <a href="/post/about" class="site-nav">
            关于
          </a>
        
      
    </div>
  </div>
  <div class="bottom-container" data-aos="flip-up" data-aos-offset="0">
    <div class="social-container">
      
        
      
        
      
        
      
        
      
        
      
    </div>
    <div class="site-description">
      道可道 非常道
    </div>
    <div class="site-footer">
      Powered by <a href="https://janl.gitee.io" target="_blank">Janl</a> | <a class="rss" href="https://janl.gitee.io/atom.xml" target="_blank">RSS</a>
    </div>
  </div>
</div>


      <div class="main-container">
        <div class="content-container" data-aos="fade-up">
          <div class="post-detail">
            <h2 class="post-title">django-simpleui组件中模型的CRUD的重写</h2>
            <div class="post-date">2022-07-26</div>
            
              <div class="feature-container" style="background-image: url('https://janl.gitee.io/post-images/django-simpleui-zu-jian-zhong-mo-xing-de-crud-de-chong-xie.png')">
              </div>
            
            <div class="post-content" v-pre>
              <p>最的工作中处理一个使用django项目，项目主要以提供restfull的api为主，但是也使用django-simpleui组件实现了一个简单的管理后台，对系统中的一些基础数据和配置进行管理，因为需求调整，需要对原来模型在CRUD时做一些额外的处理，在此记录一下处理过程。</p>
<p>一、 先说大概的使用流程</p>
<ol>
<li>先定义一个 from class, 继承至 django.form.ModelForm, 这个form中可以定义护展的表单字段，或重写模型的已有字段。</li>
<li>定义一个admin类，继承到 django.contrib.admin.ModelAdmin, 在这个类中可以重写一些方法来实现一些想要实现的功能。</li>
<li>想要自定义的from生效，需要在 admin类中指定 form = CustomForm</li>
<li>可以在admin类中指定， list_display  用于指定元组类型，列表显示字段。</li>
<li>可以在admin类中，指定fields 用于指定元组类型的表单字段。</li>
<li>当模型字段转多时，也可以通过指定fieldsets来对字段进行分组，要求一个元组，每个分组也是一个元组类型，元组的第一个元素是分组标题，第二个元素是一个字典，key是fields, value是元组类型，每个元素是字段。</li>
</ol>
<p>二、 说说CRUD的操作扩展如何实现。</p>
<ol>
<li>先说C，创建的扩展</li>
</ol>
<p>创建可以在admin类中，重写 add_view 方法，来做form的初始化，原型如下：</p>
<pre><code>def add_view(self, request, form_url='', extra_context=None):
        self.form.base_fields['fieldname'].initial = 20
        return super(UserAdmin, self).add_view(request,  form_url='', extra_context=None)
</code></pre>
<p>当保存的时候，分为两种情况，一种情况是不涉及模型的ID值，一种是不涉及ID值。<br>
不涉及使用id值的情况下：可以重写save_model方法，方法原型如下：</p>
<pre><code>    def save_model(self, request, obj, form, change):
        obj.fieldname = bool(request.POST.get('fieldname'))
        return super(UserAdmin, self).save_model(request, obj, form, change)
</code></pre>
<p>涉及使用模型id值的情况：需要重写form的save方法，方法原型如下：</p>
<pre><code>    def save(self, commit=True):
        user = super(UserForm, self).save(commit=False)
        user.save()
        ......
        # do somethings use user.id
        return user
</code></pre>
<ol start="2">
<li>
<p>说说R，读取渲染表单</p>
<p>先渲染表单change_view, 如果，所有字段都列入readonly_fields元组，可以实现一种查看方式，否则就是修改的实现。</p>
<pre><code>    def change_view(self, request, object_id, extra_context=None):
         self.form.base_fields['fieldname'].initial = False
     return super(UserAdmin, self).change_view(request, object_id, extra_context=extra_context)
</code></pre>
</li>
<li>
<p>说说U，更新处理扩展<br>
修改的实现，初始化同上，重写change_view方法</p>
</li>
</ol>
<pre><code>       def change_view(self, request, object_id, extra_context=None):
            self.form.base_fields['fieldname'].initial = False
        return super(UserAdmin, self).change_view(request, object_id, extra_context=extra_context)
</code></pre>
<p>修改内容的处理扩展处理，可以实现在重写 save_model方法中</p>
<pre><code>    def save_model(self, request, obj, form, change):
        obj.fieldname = bool(request.POST.get('fieldname'))
        return super(UserAdmin, self).save_model(request, obj, form, change)
</code></pre>
<ol start="4">
<li>最后D，删除操作扩展<br>
删除分两种情况，一处情况是修改或详情页面下的删除按钮；另一种情况是在列表页面上选择单行或多行记录进行批量删除。<br>
单个删除，可以重写delete_model方法</li>
</ol>
<pre><code>def delete_model(self, request, obj):
    # ...do somethings 
    return super(UserAdmin, self).delete_model(request, obj)
</code></pre>
<p>多条指量删除可以重写 delete_queryset方法实现。</p>
<pre><code> def delete_queryset(self, request, queryset):
        # print(&quot;delete_selected start....&quot;)
        for item in queryset:
            # ... do somethings...
        return super(UserAdmin, self).delete_queryset(request, queryset)
</code></pre>

            </div>
            
              <div class="tag-container">
                
                  <a href="https://janl.gitee.io/tag/upxStUD1Y/" class="tag">
                    python
                  </a>
                
                  <a href="https://janl.gitee.io/tag/3HBpraHKd/" class="tag">
                    django
                  </a>
                
              </div>
            
            
              <div class="next-post">
                <div class="next">下一篇</div>
                <a href="https://janl.gitee.io/post/mysql-guan-fang-jing-xiang-8029-ban-ben-xu-yao-tian-jia-mysql-files-ying-she/">
                  <h3 class="post-title">
                    mysql官方镜像8.0.29版本需要添加mysql-files映射
                  </h3>
                </a>
              </div>
            

            

          </div>

        </div>
      </div>
    </div>

    <script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script type="application/javascript">

AOS.init();

var app = new Vue({
  el: '#app',
  data: {
    menuVisible: false,
  },
})

</script>


  <script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.5.1/build/highlight.min.js"></script>
  <script>
    hljs.initHighlightingOnLoad()
  </script>





  </body>
</html>
